﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Threading;

namespace Accona.Remoting.Remoting
{
    public class ServiceAnnouncer
    {
        private readonly Guid applicationId;
        private readonly byte[] buffer;
        private readonly ISender sender;
        private readonly Stream stream;
        private bool running;

        public ServiceAnnouncer(ISender sender, Guid applicationId)
        {
            this.sender = sender;
            this.applicationId = applicationId;
            buffer = new byte[1400];
            stream = new MemoryStream(buffer);
            AppDomain.CurrentDomain.ProcessExit += Application_ApplicationExit;
        }

        private void Application_ApplicationExit(object sender, EventArgs e)
        {
            SendAnnouncements(ServiceInfo.AnnouncementAction.Remove);
        }

        public void StartAnnounce()
        {
            var thread = new Thread(Announce);
            thread.IsBackground = true;
            thread.Start();
        }

        private void Announce()
        {
            running = true;
            while (running)
            {
                Thread.Sleep(1000);
                SendAnnouncements(ServiceInfo.AnnouncementAction.Add);
            }
        }

        private void SendAnnouncements(ServiceInfo.AnnouncementAction action)
        {
            stream.Seek(0, SeekOrigin.Begin);
            var formatter = new BinaryFormatter();
            IList<ServiceInfo> announcements =
                RemoteExecutionRepository.Instance.SupportedInterfaces().Select(a => new ServiceInfo
                                                                                         {
                                                                                             ServerId = applicationId,
                                                                                             SupportedInterface =
                                                                                                 a.FullName,
                                                                                             Action = action
                                                                                         }).ToList();
            formatter.Serialize(stream, announcements);
            sender.Send(buffer);
        }
    }
}